package com.bright.hxj.qchz.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class QCHZExpressUtil {


//    public String explainGongShi(NewRules newRules,List<Object> zt,String keyword,String tableName, Map<String, Map<String, Map<String, String>>> gsTableDataMap,List<String> gsIdList,String tableDescription){
//        //NewRules newRules,List<String> data
//        //发现稽核公式有两种一是计算值对比左右值，二是验证字段的关系
//        //例如：a+b=c  a!="" and (a=1 or b=1 or c=1),现在做的只是第一种
//        //表名.字段名!=null and (表名.字段名1=1 or 表名.字段名2=1 or 表名.字段名3=1)
//        //表名.字段名>值名=表名.字段名&+表名.字段名>值名&+表名.字段名>值名
//        //String gongShi=newRules.getRule();
//        //左右操作符 =,<,>,!=,<=,>=
//        //计算符 +，-，*，/
//        //字段名 .
//        //值名 #
//        //循环 &
//        //两个字段确定一个值的，两个列名用 @ 比如zcNo=zc01 的zms  ---->  zms@zcNo#zc01
//        //稽核公式表名字段名等必须与配置表的内容一致如filelist表的tablename=qcsj18_ZCFZ_19那么公式表内就不能为qcsj18_zcfz_19
//
//        //2021-09-15
//        //
//        String retValue="";
//        //System.out.println(newRules.getDescription()+zt.get(0)+zt.get(1));
//
//
//        //String gongShi="table1.column1@column2#line1=table2.column1&+table1.column1#line2&+table1.column1#line3-table3.column1#line1";
//        //对于业务优化
//        //优化1将稽核公式区分标间公式和表内公式
//        //标间公式只取一次，表内公式取相关表数据
//        Map<String, List<String>> map = new HashMap<String, List<String>>();
//        if(newRules.getType()==1){
//            Long mapTime=System.currentTimeMillis();
//            if(newRules.getGsType()==1){
//                map.put(tableName,gsIdList);
//            }
//            if(newRules.getGsType()==2){
//                List<String> tableNames=getTableNames(newRules.getTableNameStr());
//                // 跨表情形
//                for (String table : tableNames) {
//                    List<String> idList = (List<String>) RedisUtil.lrange(keyword + ":" + table + ":" + zt.get(0) + ":List", 0, -1);
//                    map.put(table, idList);
//                }
//            }
//            Long mapTime2=System.currentTimeMillis();
//
//            retValue = exRuleByType1(newRules, keyword, zt, tableName,map,gsTableDataMap,tableDescription);
//            Long mapTime3=System.currentTimeMillis();
//            //System.out.println("写入时间："+(mapTime2-mapTime));
//            //System.out.println("稽核时间："+(mapTime3-mapTime2));
//        }
//
//        //type2类型只支持表内关系，条件判断类型
//        if (newRules.getType()==2){
//
//            List<String> idList=(List<String>) RedisUtil.lrange(keyword+":"+tableName+":"+zt.get(0)+":List",0,-1);
//            map.put(tableName,idList);
//            retValue = exRuleByType2(newRules, keyword, zt,tableName,idList,tableDescription);
//        }
//
//        //type3类型只支持表内关系（循环整表，每条纪录都要稽核）
//        if(newRules.getType()==3){
//            List<String> idList=(List<String>) RedisUtil.lrange(keyword+":"+tableName+":"+zt.get(0)+":List",0,-1);
//            map.put(tableName,idList);
//            retValue = exRuleByType3(newRules, keyword, zt, tableName,map,gsTableDataMap,tableDescription);
//        }
//
//        return retValue;
//
//    }

    //NewRules newRules,List<String> data
    //发现稽核公式有两种一是计算值对比左右值，二是验证字段的关系
    //例如：a+b=c  a!="" and (a=1 or b=1 or c=1),现在做的只是第一种
    //表名.字段名!=null and (表名.字段名1=1 or 表名.字段名2=1 or 表名.字段名3=1)
    //表名.字段名>值名=表名.字段名&+表名.字段名>值名&+表名.字段名>值名
    //String gongShi=newRules.getRule();
    //左右操作符 =,<,>,!=,<=,>=
    //计算符 +，-，*，/
    //字段名 .
    //值名 #
    //循环 &
    //两个字段确定一个值的，两个列名用 @ 比如zcNo=zc01 的zms  ---->  zms@zcNo#zc01
    //稽核公式表名字段名等必须与配置表的内容一致如filelist表的tablename=qcsj18_ZCFZ_19那么公式表内就不能为qcsj18_zcfz_19


    public static List<String> checkRuleType1(String ztId, String tableDescription, String ruleExpress, String ruleDescription, Map<String, List<Map<String, String>>> tableDataMap) {
        // 类型1 竖表校验 + 跨表校验

//        List<Object> zt = Arrays.asList((Object) 0, ztId);

//        Long type1Begin = System.currentTimeMillis();
//        String ruleExpress = newRules.getRule();
        String leftAndRightOpt = "";
        List<String> retValue = new ArrayList<>();
//        Integer num = 0;
        List<BigDecimal> rvalue = new ArrayList<BigDecimal>();
        leftAndRightOpt = getLeftAndRightOpt(ruleExpress, leftAndRightOpt);
        List<List<String>> valueList = getValueLists(ruleExpress, leftAndRightOpt);


//        Long tableDataTime = System.currentTimeMillis();

//        Long tableDataTime2 = System.currentTimeMillis();
        //System.out.println("准备数据："+(tableDataTime2-tableDataTime));
        // 跨表取数移到了checkRuleType1被调用之前
        for (List<String> dataSub : valueList) {
            BigDecimal tempValue = BigDecimal.valueOf(0);
            String lastOption = "start";
            for (String dataStr : dataSub) {
                String lineName = "";
                String tiaoJianColumnName = "";
                String quZhiColumnName = "";
                String tableName = "";

                String option = dataStr.substring(dataStr.length() - 1);
                if (option.equalsIgnoreCase("+") || option.equalsIgnoreCase("-")) {
                    dataStr = dataStr.substring(0, dataStr.length() - 1);
                }
                boolean isAll = false;// 是否取所有数据行该字段的合计值
                if (dataStr.contains("&")) { // 校验表达式以&结尾
                    dataStr = dataStr.substring(0, dataStr.length() - 1);
                    isAll = true;
                }
                if (dataStr.contains("#")) {
                    lineName = dataStr.split("#")[1];
                }
                if (dataStr.contains(".")) {
                    String columnNameStr = dataStr.split("\\.")[1];
                    String columnName = columnNameStr.split("#")[0];

                    if (columnName.contains("@")) {
                        tiaoJianColumnName = columnName.split("@")[1];
                        quZhiColumnName = columnName.split("@")[0];
                    }
                    tableName = dataStr.split("\\.")[0];
                }
                BigDecimal oneValue = new BigDecimal("0");
                String oneValueStr = "0";

                if (!tableName.equalsIgnoreCase("")) {
//                    List<String> idList=new ArrayList<String>();
//                    idList=mapIdList.get(tableName);
//                    if(idList.size()>1){
//                        Collections.reverse(idList);
//                    }

//                    num=idList.size();
                    boolean isFieldEmpty = true; // 检查该表上传的数据是否有传这个字段 避免因为漏传字段而跳过校验
//                    for (String idStr : idList) {
                    for (Map<String, String> eachMap : tableDataMap.get(tableName)) {
                        if (isAll) {// 是否取所有数据行该字段的合计值
                            String lcolumn = "";
                            if (lineName.equalsIgnoreCase("")) {
                                lcolumn = dataStr.split("\\.")[1];
                            } else {
                                lcolumn = quZhiColumnName;
                                String tiaojian = eachMap.get(tiaoJianColumnName);
                                if (!StringUtils.equals(tiaojian, lineName)) {
                                    continue;
                                }
                            }
                            isFieldEmpty = false;
                            oneValueStr = eachMap.get(lcolumn);

                            if (oneValueStr.equals("null") || oneValueStr.equals("") || oneValueStr.equals("0.00")) {
                                oneValueStr = "0";
                            } else {
                                oneValue = oneValue.add(new BigDecimal(oneValueStr));
                            }
                        } else {
                            Map<String, String> map;
                            map = eachMap;
                            String tiaojian = map.get(tiaoJianColumnName);
//
                            if (StringUtils.equalsIgnoreCase(tiaojian, lineName)) {
                                isFieldEmpty = false;
                                oneValueStr = map.get(quZhiColumnName);
                                if (oneValueStr.equals("null") || oneValueStr.equals("") || oneValueStr.equals("0.00")) {
                                    oneValueStr = "0";
                                }
                                oneValue = new BigDecimal(oneValueStr);
                                break;
                            }
                            oneValue = new BigDecimal(oneValueStr);
                        }


                    }
                    if (isFieldEmpty) {
                        retValue.add("数据校验时出错：第三方上传的" + tableName + "数据中找不到" + tiaoJianColumnName + "字段，或该字段不存在值为" + lineName + "的数据行！");
                        return retValue;
                    }
                }
                if (dataStr.toUpperCase().contains("COUNT")) { // 表名COUNT  或  条数COUNT
                    String numStr = dataStr.substring(0, dataStr.length() - 5); // 截掉尾部的COUNT
                    if (isInteger(numStr)) {
                        oneValue = new BigDecimal(numStr);
                    } else {
//                        String count=String.valueOf(RedisUtil.llen(keyword+":"+numStr+":"+zt.get(0)+":List"));
                        // 这里应该是计算该账套下该表有多少条数据
                        List<Map<String, String>> maps = tableDataMap.get(numStr);
                        if (maps == null) {
                            retValue.add("校验表达式设置有误，取不到该表数据行数：" + numStr);
                            return retValue;
                        }
                        oneValue = new BigDecimal(maps.size());
                    }

                }
//                System.out.println(tempValue + " " + lastOption + " " + oneValue);
                if (lastOption.equalsIgnoreCase("start")) {
                    tempValue = oneValue;
                } else if (lastOption.equalsIgnoreCase("+")) {
                    tempValue = tempValue.add(oneValue);

                } else if (lastOption.equalsIgnoreCase("-")) {
                    tempValue = tempValue.subtract(oneValue);

                } else if (lastOption.equalsIgnoreCase("*")) {
                    tempValue = tempValue.multiply(oneValue);

                } else if (lastOption.equalsIgnoreCase("/")) {
                    tempValue = tempValue.divide(oneValue, 20, RoundingMode.HALF_UP);

//                } else {
////                    tempValue = tempValue;
                }
                //System.out.println("当前子公式的值："+oneValue);
                //System.out.println("相加后的值："+tempValue);
                lastOption = option;
            }

            rvalue.add(tempValue);

        }
//        retValue = checkValue(newRules, zt, rvalue, leftAndRightOpt, null, tableDescription);
        String checkValueResult = checkValue("稽核单位：" + ztId, ruleDescription, tableDescription, rvalue, leftAndRightOpt);

//        Long type1End=System.currentTimeMillis();
//        Long type1=type1End-type1Begin;
//        if(type1>10){
//            System.out.println(zt.get(1)+newRules.getDescription()+":"+newRules.getRule()+gstableName+"数量："+num+"执行type1公式耗时："+type1);
//        }
//        if (StringUtils.isNotEmpty(retValue)) {
//            return new RoleInfo(retValue);
//        }
        if (StringUtils.isNotEmpty(checkValueResult)) {
            retValue.add(checkValueResult);
        }
        return retValue;
//        return null;
    }

//    public static RoleInfo checkRuleType1(String ztId, Duijie_ShiJieShouDeploy deploy, NewRules newRules, Map<String, List<Map<String, String>>> tableDataMap) {
//        // 类型1 竖表校验 + 跨表校验
//
//        List<Object> zt = Arrays.asList((Object) 0, ztId);
//
////        Long type1Begin = System.currentTimeMillis();
//        String gongShi = newRules.getRule();
//        String leftAndRightOpt = "";
//        String retValue = "";
////        Integer num = 0;
//        List<BigDecimal> rvalue = new ArrayList<BigDecimal>();
//        leftAndRightOpt = getLeftAndRightOpt(gongShi, leftAndRightOpt);
//        List<List<String>> valueList = getValueLists(gongShi, leftAndRightOpt);
//
//
////        Long tableDataTime = System.currentTimeMillis();
//
////        Long tableDataTime2 = System.currentTimeMillis();
//        //System.out.println("准备数据："+(tableDataTime2-tableDataTime));
//        // 跨表取数移到了checkRuleType1被调用之前
//        for (List<String> dataSub : valueList) {
//            BigDecimal tempValue = BigDecimal.valueOf(0);
//            String lastOption = "start";
//            for (String dataStr : dataSub) {
//                String lineName = "";
//                String tiaoJianColumnName = "";
//                String quZhiColumnName = "";
//                String tableName = "";
//
//                String option = dataStr.substring(dataStr.length() - 1);
//                if (option.equalsIgnoreCase("+") || option.equalsIgnoreCase("-")) {
//                    dataStr = dataStr.substring(0, dataStr.length() - 1);
//                }
//                boolean isAll = false;
//                if (dataStr.contains("&")) { // 校验表达式以&结尾
//                    dataStr = dataStr.substring(0, dataStr.length() - 1);
//                    isAll = true;
//                }
//                if (dataStr.contains("#")) {
//                    lineName = dataStr.split("#")[1];
//                }
//                if (dataStr.contains(".")) {
//                    String columnNameStr = dataStr.split("\\.")[1];
//                    String columnName = columnNameStr.split("#")[0];
//
//                    if (columnName.contains("@")) {
//                        tiaoJianColumnName = columnName.split("@")[1];
//                        quZhiColumnName = columnName.split("@")[0];
//                    }
//                    tableName = dataStr.split("\\.")[0];
//                }
//                BigDecimal oneValue = new BigDecimal("0");
//                String oneValueStr = "0";
//
//                if (!tableName.equalsIgnoreCase("")) {
////                    List<String> idList=new ArrayList<String>();
////                    idList=mapIdList.get(tableName);
////                    if(idList.size()>1){
////                        Collections.reverse(idList);
////                    }
//
////                    num=idList.size();
////                    for (String idStr : idList) {
//                    for (Map<String, String> eachMap : tableDataMap.get(tableName)) {
//                        if (isAll) {
//                            String lcolumn = "";
//                            if (lineName.equalsIgnoreCase("")) {
//                                lcolumn = dataStr.split("\\.")[1];
//                            } else {
//                                lcolumn = quZhiColumnName;
//                                String tiaojian = eachMap.get(tiaoJianColumnName);
//                                if (!tiaojian.equalsIgnoreCase(lineName)) {
//                                    continue;
//                                }
//                            }
//                            oneValueStr = eachMap.get(lcolumn);
//
//                            if (oneValueStr.equals("null") || oneValueStr.equals("") || oneValueStr.equals("0.00")) {
//                                oneValueStr = "0";
//                            } else {
//                                oneValue = oneValue.add(new BigDecimal(oneValueStr));
//                            }
//                        } else {
//                            Map<String, String> map;
//                            map = eachMap;
//                            String tiaojian = map.get(tiaoJianColumnName);
//                            if (tiaojian == null) {
//                                return new RoleInfo("数据校验时出错：第三方上传的数据中找不到" + tiaoJianColumnName + "字段！");
//                            }
//                            if (tiaojian.equalsIgnoreCase(lineName)) {
//                                oneValueStr = map.get(quZhiColumnName);
//                                if (oneValueStr.equals("null") || oneValueStr.equals("") || oneValueStr.equals("0.00")) {
//                                    oneValueStr = "0";
//                                }
//                                oneValue = new BigDecimal(oneValueStr);
//                                break;
//                            }
//                            oneValue = new BigDecimal(oneValueStr);
//                        }
//
//
//                    }
//                }
//                if (dataStr.toUpperCase().contains("COUNT")) { // 表名COUNT  或  条数COUNT
//                    String numStr = dataStr.substring(0, dataStr.length() - 5); // 截掉尾部的COUNT
//                    if (isInteger(numStr)) {
//                        oneValue = new BigDecimal(numStr);
//                    } else {
////                        String count=String.valueOf(RedisUtil.llen(keyword+":"+numStr+":"+zt.get(0)+":List"));
//                        // 这里应该是计算该账套下该表有多少条数据
//                        List<Map<String, String>> maps = tableDataMap.get(numStr);
//                        if (maps == null) {
//                            return new RoleInfo("校验表达式设置有误，取不到该表数据：" + numStr);
//                        }
//                        oneValue = new BigDecimal(maps.size());
//                    }
//
//                }
////                System.out.println(tempValue + " " + lastOption + " " + oneValue);
//                if (lastOption.equalsIgnoreCase("start")) {
//                    tempValue = oneValue;
//                } else if (lastOption.equalsIgnoreCase("+")) {
//                    tempValue = tempValue.add(oneValue);
//
//                } else if (lastOption.equalsIgnoreCase("-")) {
//                    tempValue = tempValue.subtract(oneValue);
//
//                } else if (lastOption.equalsIgnoreCase("*")) {
//                    tempValue = tempValue.multiply(oneValue);
//
//                } else if (lastOption.equalsIgnoreCase("/")) {
//                    tempValue = tempValue.divide(oneValue, 20, BigDecimal.ROUND_HALF_UP);
//
////                } else {
//////                    tempValue = tempValue;
//                }
//                //System.out.println("当前子公式的值："+oneValue);
//                //System.out.println("相加后的值："+tempValue);
//                lastOption = option;
//            }
//
//            rvalue.add(tempValue);
//
//        }
//        retValue = checkValue(newRules, zt, rvalue, leftAndRightOpt, deploy.getType(), deploy.getDescription());
////        Long type1End=System.currentTimeMillis();
////        Long type1=type1End-type1Begin;
////        if(type1>10){
////            System.out.println(zt.get(1)+newRules.getDescription()+":"+newRules.getRule()+gstableName+"数量："+num+"执行type1公式耗时："+type1);
////        }
//        if (StringUtils.isNotEmpty(retValue)) {
//            return new RoleInfo(retValue);
//        }
//
//        return null;
//    }


    public static List<String> checkRuleType2(String ztId, String tableDescription, String ruleExpress, String ruleDescription, List<Map<String, String>> tableDataList) {
//        List<Object> zt = Arrays.asList((Object) 0, ztId);

        Long type2Begin = System.currentTimeMillis();
        List<String> rvalue = new ArrayList<>();
//        String ruleExpress = newRules.getRule();
        List<List<String>> tijiaos = getTiaoJian(ruleExpress);
        String oldValue = "";
        //logger.error("稽核公式："+newRules.getDescription()+newRules.getTableName());
        //List<String> idList=(List<String>) CommonUtil.lrange(keyword+":"+tableName+":"+zt.get(0)+":List",0,-1);
//        if (idList.size() != 0) {
        //如果是表间公式的话就先把整表的数据准备好，避免每个子公式重复取
//            Map<String, Map<String, Map<String, String>>> tableDataMap = getTableDataMapType1(keyword, tableName, idList);
//            for (String id : idList) {
        int i = 1;
        for (Map<String, String> map : tableDataList) {
            for (List<String> sub : tijiaos) {
                //System.out.println(sub);
                String value = "";
                String tjItem = sub.get(0);
                String opt = sub.get(1);
                value = checkItem(tjItem, map);
                if (opt.equals("&") || opt.equals("|")) {
                    oldValue = checkItemCeng(opt, value, oldValue);
                } else {
                    oldValue = value;
                }
            }
            boolean a = Boolean.parseBoolean(oldValue);
            if (a) {
                rvalue.add("稽核单位：" + ztId + tableDescription + " 第" + i + "行 " + ruleDescription);
            }
            i++;
        }
//        }
        Long type2End = System.currentTimeMillis();
        Long type2 = (type2End - type2Begin);
//        if(type2>80){
//            System.out.println(tableName+"数量："+idList.size()+"执行type2公式耗时："+type2);
//        }
//        if (StringUtils.isNotEmpty(rvalue)) {
//            return new RoleInfo(rvalue);
//        }

        return rvalue;
    }


//    public static List<String> checkRuleType2(String ztId, Duijie_ShiJieShouDeploy deploy, NewRules newRules, Map<String, List<Map<String, String>>> tableDataMap) {
//        List<Object> zt = Arrays.asList((Object) 0, ztId);
//
//        Long type2Begin = System.currentTimeMillis();
//        String rvalue = "";
//        String gongShi = newRules.getRule();
//        List<List<String>> tijiaos = getTiaoJian(gongShi);
//        String oldValue = "";
//        //logger.error("稽核公式："+newRules.getDescription()+newRules.getTableName());
//        //List<String> idList=(List<String>) CommonUtil.lrange(keyword+":"+tableName+":"+zt.get(0)+":List",0,-1);
////        if (idList.size() != 0) {
//        //如果是表间公式的话就先把整表的数据准备好，避免每个子公式重复取
////            Map<String, Map<String, Map<String, String>>> tableDataMap = getTableDataMapType1(keyword, tableName, idList);
////            for (String id : idList) {
//        for (Map<String, String> map : tableDataMap.get(deploy.getType())) {
//            for (List<String> sub : tijiaos) {
//                //System.out.println(sub);
//                String value = "";
//                String tjItem = sub.get(0);
//                String opt = sub.get(1);
//                value = checkItem(tjItem, newRules, zt, map);
//                if (opt.equals("&") || opt.equals("|")) {
//                    oldValue = checkItemCeng(opt, value, oldValue);
//                } else {
//                    oldValue = value;
//                }
//            }
//            Boolean a = Boolean.parseBoolean(oldValue);
//            if (a) {
//                rvalue += "稽核单位：" + zt.get(1) + " " + deploy.getDescription() + " " + newRules.getDescription();
//            }
//        }
////        }
//        Long type2End = System.currentTimeMillis();
//        Long type2 = (type2End - type2Begin);
////        if(type2>80){
////            System.out.println(tableName+"数量："+idList.size()+"执行type2公式耗时："+type2);
////        }
//        if (StringUtils.isNotEmpty(rvalue)) {
//            return new RoleInfo(rvalue);
//        }
//
//        return null;
//    }

    public static List<String> checkRuleType3(String ztId, String tableDescription, String ruleExpress, String ruleDescription, List<Map<String, String>> tableDataList) {
//        List<Object> zt = Arrays.asList((Object) 0, ztId);

//        String ruleExpress = newRules.getRule();
        String leftAndRightOpt = "";
        List<String> retValue = new ArrayList<>();
//        Integer num = 0;

        leftAndRightOpt = getLeftAndRightOpt(ruleExpress, leftAndRightOpt);
        List<List<String>> valueList = getValueLists(ruleExpress, leftAndRightOpt);


        //System.out.println(valueList);
        //如果是表内公式的话就先把整表的数据准备好，避免每个子公式重复取
//        Long tableDataTime = System.currentTimeMillis();
//        Map<String, Map<String, Map<String, String>>> tableDataMap = new HashMap<String, Map<String, Map<String, String>>>();

//        tableDataMap = gsTableDataMap;
//        List<String> idList = new ArrayList<String>();
//        idList = mapIdList.get(gstableName);
//        if (idList.size() > 1) {
//            Collections.reverse(idList);
//        }

//        for (String idStr : idList) {
        int i = 1;
        for (Map<String, String> map : tableDataList) {
            List<BigDecimal> rvalue = new ArrayList<BigDecimal>();
            for (List<String> dataSub : valueList) {
                BigDecimal tempValue = BigDecimal.valueOf(0);
                String lastOption = "start";
                for (String dataStr : dataSub) {
                    String lineName = "";
                    String tiaoJianColumnName = "";
                    String quZhiColumnName = "";
                    String tableName = "";

                    String option = dataStr.substring(dataStr.length() - 1);
                    if (option.equalsIgnoreCase("+") || option.equalsIgnoreCase("-")) {
                        dataStr = dataStr.substring(0, dataStr.length() - 1);
                    }
                    if (dataStr.contains("#")) {
                        lineName = dataStr.split("#")[1];
                    }
                    if (dataStr.contains(".")) {
                        String columnNameStr = dataStr.split("\\.")[1];
                        String columnName = columnNameStr.split("#")[0];

                        if (columnName.contains("@")) {
                            tiaoJianColumnName = columnName.split("@")[1];
                            quZhiColumnName = columnName.split("@")[0];
                        }
                        tableName = dataStr.split("\\.")[0];
                    }
                    BigDecimal oneValue = new BigDecimal("0");
                    String oneValueStr = "0";


                    String lcolumn = "";
                    if (lineName.equalsIgnoreCase("")) {
                        lcolumn = dataStr.split("\\.")[1];
                    } else {
                        lcolumn = quZhiColumnName;
                        String tiaojian = map.get(tiaoJianColumnName);
                        if (!tiaojian.equalsIgnoreCase(lineName)) {
                            continue;
                        }
                    }
                    oneValueStr = map.get(lcolumn);
                    if (oneValueStr == null || oneValueStr.equals("null") || oneValueStr.equals("") || oneValueStr.equals("0.00")) {
                        oneValueStr = "0";
                    } else {
                        oneValue = new BigDecimal(oneValueStr);
                    }


                    if (lastOption.equalsIgnoreCase("start")) {
                        tempValue = oneValue;
                    } else if (lastOption.equalsIgnoreCase("+")) {
                        tempValue = tempValue.add(oneValue);

                    } else if (lastOption.equalsIgnoreCase("-")) {
                        tempValue = tempValue.subtract(oneValue);

                    } else if (lastOption.equalsIgnoreCase("*")) {
                        tempValue = tempValue.multiply(oneValue);

                    } else if (lastOption.equalsIgnoreCase("/")) {
                        tempValue = tempValue.divide(oneValue, 20, BigDecimal.ROUND_HALF_UP);

//                    } else {
//                        tempValue = tempValue;
                    }
                    lastOption = option;
                }
                rvalue.add(tempValue);
            }

//            retValue += checkValue(newRules, zt, rvalue, leftAndRightOpt, deploy.getType(), deploy.getDescription());
            String checkValueResult = checkValue("稽核单位 " + ztId, ruleDescription, tableDescription + " 第" + i + "行 ", rvalue, leftAndRightOpt);
            if (StringUtils.isNotEmpty(checkValueResult)) {
                retValue.add(checkValueResult);
            }
            i++;
        }

        return retValue;
    }

//    public static List<String> checkRuleType3(String ztId, Duijie_ShiJieShouDeploy deploy, NewRules newRules, Map<String, List<Map<String, String>>> tableDataMap) {
//        List<Object> zt = Arrays.asList((Object) 0, ztId);
//
//        String gongShi = newRules.getRule();
//        String leftAndRightOpt = "";
//        String retValue = "";
//        Integer num = 0;
//
//        leftAndRightOpt = getLeftAndRightOpt(gongShi, leftAndRightOpt);
//        List<List<String>> valueList = getValueLists(gongShi, leftAndRightOpt);
//
//
//        //System.out.println(valueList);
//        //如果是表内公式的话就先把整表的数据准备好，避免每个子公式重复取
//        Long tableDataTime = System.currentTimeMillis();
////        Map<String, Map<String, Map<String, String>>> tableDataMap = new HashMap<String, Map<String, Map<String, String>>>();
//
////        tableDataMap = gsTableDataMap;
////        List<String> idList = new ArrayList<String>();
////        idList = mapIdList.get(gstableName);
////        if (idList.size() > 1) {
////            Collections.reverse(idList);
////        }
//
////        for (String idStr : idList) {
//        for (Map<String, String> map : tableDataMap.get(deploy.getType())) {
//            List<BigDecimal> rvalue = new ArrayList<BigDecimal>();
//            for (List<String> dataSub : valueList) {
//                BigDecimal tempValue = BigDecimal.valueOf(0);
//                String lastOption = "start";
//                for (String dataStr : dataSub) {
//                    String lineName = "";
//                    String tiaoJianColumnName = "";
//                    String quZhiColumnName = "";
//                    String tableName = "";
//
//                    String option = dataStr.substring(dataStr.length() - 1);
//                    if (option.equalsIgnoreCase("+") || option.equalsIgnoreCase("-")) {
//                        dataStr = dataStr.substring(0, dataStr.length() - 1);
//                    }
//                    if (dataStr.contains("#")) {
//                        lineName = dataStr.split("#")[1];
//                    }
//                    if (dataStr.contains(".")) {
//                        String columnNameStr = dataStr.split("\\.")[1];
//                        String columnName = columnNameStr.split("#")[0];
//
//                        if (columnName.contains("@")) {
//                            tiaoJianColumnName = columnName.split("@")[1];
//                            quZhiColumnName = columnName.split("@")[0];
//                        }
//                        tableName = dataStr.split("\\.")[0];
//                    }
//                    BigDecimal oneValue = new BigDecimal("0");
//                    String oneValueStr = "0";
//
//
//                    String lcolumn = "";
//                    if (lineName.equalsIgnoreCase("")) {
//                        lcolumn = dataStr.split("\\.")[1];
//                    } else {
//                        lcolumn = quZhiColumnName;
//                        String tiaojian = map.get(tiaoJianColumnName);
//                        if (!tiaojian.equalsIgnoreCase(lineName)) {
//                            continue;
//                        }
//                    }
//                    oneValueStr = map.get(lcolumn);
//                    if (oneValueStr.equals("null") || oneValueStr.equals("") || oneValueStr.equals("0.00")) {
//                        oneValueStr = "0";
//                    } else {
//                        oneValue = new BigDecimal(oneValueStr);
//                    }
//
//
//                    if (lastOption.equalsIgnoreCase("start")) {
//                        tempValue = oneValue;
//                    } else if (lastOption.equalsIgnoreCase("+")) {
//                        tempValue = tempValue.add(oneValue);
//
//                    } else if (lastOption.equalsIgnoreCase("-")) {
//                        tempValue = tempValue.subtract(oneValue);
//
//                    } else if (lastOption.equalsIgnoreCase("*")) {
//                        tempValue = tempValue.multiply(oneValue);
//
//                    } else if (lastOption.equalsIgnoreCase("/")) {
//                        tempValue = tempValue.divide(oneValue, 20, BigDecimal.ROUND_HALF_UP);
//
//                    } else {
//                        tempValue = tempValue;
//                    }
//                    lastOption = option;
//                }
//                rvalue.add(tempValue);
//            }
//
//            retValue += checkValue(newRules, zt, rvalue, leftAndRightOpt, deploy.getType(), deploy.getDescription());
//        }
//
//        if (StringUtils.isNotEmpty(retValue)) {
//            return new RoleInfo(retValue);
//        }
//
//        return null;
//    }

//    private static List<String> getTableNames(String tableNameStr) {
//        List<String> rvalue = new ArrayList<String>();
//        String[] temp = tableNameStr.split(",");
//        for (int i = 0; i < temp.length; i++) {
//            rvalue.add(temp[i]);
//        }
//        return rvalue;
//    }

    private static String checkItemCeng(String opt, String value, String oldValue) {
        String rvalue = "";
        Boolean result = false;
        if (opt.equals("&")) {
            result = Boolean.parseBoolean(value) && Boolean.parseBoolean(oldValue);
        }
        if (opt.equals("|")) {
            result = Boolean.parseBoolean(value) || Boolean.parseBoolean(oldValue);
        }
        rvalue = result.toString();
        return rvalue;
    }

    private static String checkItem(String str, Map<String, String> map) {
        //System.out.println(str);
        String rvalue = "";
        List<String> rightValueList = new ArrayList<String>();
        String regexStr = "([^\\&|^\\|]+)(\\&|\\|)";
        Pattern p = Pattern.compile(regexStr);
        Matcher m = p.matcher(str);
        while (m.find()) {
            rightValueList.add(m.group());
        }
        if (rightValueList.size() == 0) {
            rightValueList.add(str);
        } else {
            String lastStr = rightValueList.get(rightValueList.size() - 1);
            String opt = "\\" + lastStr.substring(lastStr.length() - 1);
            String[] temp = str.split(opt);
            rightValueList.add(temp[temp.length - 1]);
        }
        String oldValue = "";
        String opt = "";
        for (String s : rightValueList) {


            Integer index = rightValueList.indexOf(s);
            s = s.trim();

            if (index != rightValueList.size() - 1) {
                opt = s.substring(s.length() - 1);
                s = s.substring(0, s.length() - 1);

            }
            s = s.replace(" ", "");
            String leftAndRightOpt = "";
            leftAndRightOpt = getLeftAndRightOpt(s, leftAndRightOpt);
            String[] temp = s.split(leftAndRightOpt);
            String left = temp[0];
            String right = temp[1];
            String tableName = "";
            String leftColumnName = "";
            String rightColumnName = "";
            String[] temp3 = new String[2];
            Boolean isjdz = false;
            if (left.contains(".")) {
                tableName = left.split("\\.")[0];
                leftColumnName = left.split("\\.")[1];
            }
            if (right.contains(".")) {
                rightColumnName = right.split("\\.")[1];
            } else {
                isjdz = true;
            }

            if (StringUtils.isNotEmpty(tableName)) {
//                Map<String, String> map = tableDataMap.get(tableName).get(id);
                //Map<String,String> map=CommonUtil.hgetall(keyword+":"+tableName + ":" + id);
                temp3[0] = map.get(leftColumnName);
                //temp3[0]=(String) CommonUtil.hget(keyword+":"+tableName + ":" + id, leftColumnName);
                if (!isjdz) {
                    temp3[1] = map.get(rightColumnName);
                    //temp3[1]=(String) CommonUtil.hget(keyword+":"+tableName + ":" + id, rightColumnName);
                } else {
                    temp3[1] = right;
                }
                if (StringUtils.isEmpty(temp3[0])) {
                    temp3[0] = "null";
                } else
//                if (temp3[0].equals("")) {
//                    temp3[0] = "null";
//                }
                if (temp3[0].contains("0.0")) {
                    temp3[0] = "0";
                }
                Boolean result = checkResult(temp3, leftAndRightOpt);
                if (!oldValue.equals("")) {
                    oldValue = checkItemCeng(opt, result.toString(), oldValue).toString();
                } else {
                    oldValue = result.toString();
                }
                //System.out.println(result);
            }

        }


        rvalue = oldValue;

        return rvalue;
    }


    private static List<List<String>> getTiaoJian(String ruleStr) {

        List<List<String>> rvalue = new ArrayList<List<String>>();
        List<Integer> indexs = countStr(ruleStr, "(");
        Integer jisu = 0;
        for (Integer sub : indexs) {
            List<String> r = new ArrayList<String>();
            String str = ruleStr.substring(jisu, sub);
            str = str.replaceAll("\\(", "");
            str = str.replaceAll("\\)", "");
            str = str.trim();

            if (indexs.indexOf(sub) != indexs.size() - 1) {
                r.add(str.substring(0, str.length() - 1));
            } else {
                r.add(str);
            }
            r.add(str.substring(str.length() - 1));
            jisu = sub;
            rvalue.add(r);
        }
        Collections.reverse(rvalue);
        //System.out.println(rvalue);
        return rvalue;
    }

    private static List<Integer> countStr(String str, String sToFind) {
        List<Integer> num = new ArrayList<Integer>();
        int index = 0;
        int strLen = str.length();
        while (str.contains(sToFind)) {
            index += str.indexOf(sToFind);
            str = str.substring(str.indexOf(sToFind) + sToFind.length());
            num.add(index);
        }
        num.add(strLen);
        return num;
    }

//    private static Map<String, Map<String, Map<String, String>>> getTableDataMapType1(String keyword, String gstableName, List<String> idList) {
//        Map<String, Map<String, Map<String, String>>> tableDataMap = new HashMap<String, Map<String, Map<String, String>>>();
//        Map<String, Map<String, String>> tableDataList = new HashMap<String, Map<String, String>>();
//        if (idList.size() > 1) {
//            Collections.reverse(idList);
//        }
//        for (String idStr : idList) {
//            Map<String, String> map = CommonUtil.hgetall(keyword + ":" + gstableName + ":" + idStr);
//            tableDataList.put(idStr, map);
//        }
//        tableDataMap.put(gstableName, tableDataList);
//        return tableDataMap;
//    }

//    private static Map<String, Map<String, Map<String, String>>> getTableDataMapType2(NewRules newRules, String keyword, String gstableName, Map<String, List<String>> mapIdList) {
//        Map<String, Map<String, Map<String, String>>> tableDataMap = new HashMap<String, Map<String, Map<String, String>>>();
//        Map<String, Map<String, String>> tableDataList = new HashMap<String, Map<String, String>>();
//
//        List<String> tableNames = getTableNames(newRules.getTableNameStr());
//        for (String table : tableNames) {
//
//            List<String> idList = mapIdList.get(table);
//            if (idList.size() > 1) {
//                Collections.reverse(idList);
//            }
//            for (String idStr : idList) {
//                Map<String, String> map = CommonUtil.hgetall(keyword + ":" + table + ":" + idStr);
//                tableDataList.put(idStr, map);
//            }
//            tableDataMap.put(table, tableDataList);
//        }
//
//        return tableDataMap;
//    }

    private static List<List<String>> getValueLists(String gongShi, String leftAndRightOpt) {
        String[] tempStr = gongShi.split(leftAndRightOpt);
        String leftValueStr = tempStr[0];
        String rightValueStr = tempStr[1];
        List<List<String>> valueList = new ArrayList<List<String>>();
        List<String> leftValueList = new ArrayList<String>();
        List<String> rightValueList = new ArrayList<String>();
        String regexStr = "([^\\-|^\\+]+)(\\-|\\+)";
        Pattern p = Pattern.compile(regexStr);
        Matcher m = p.matcher(leftValueStr);
        setValueList(leftValueStr, valueList, leftValueList, m);
        m = p.matcher(rightValueStr);
        setValueList(rightValueStr, valueList, rightValueList, m);
        return valueList;
    }

    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

//    private static String checkValue(NewRules newRules, List<Object> zt, List<BigDecimal> rvalue, String leftAndRightOpt, String gstableName, String tableDescription) {
//        String retValue = "";
////        String[] temp=new String[2];
////        temp[0]=rvalue.get(0).toString();
////        temp[1]=rvalue.get(1).toString();
//        Boolean isSuccess = false;
//        isSuccess = checkResult2(rvalue, leftAndRightOpt);
//        if (isSuccess) {
//            retValue = "稽核单位：" + zt.get(1) + " " + tableDescription + " " + newRules.getDescription() + " 左值：" + rvalue.get(0).toString() + " 右值：" + rvalue.get(1).toString();
//        }
//        //System.out.println(retValue);
//        return retValue;
//    }

    private static String checkValue(String messageHead, String ruleDescription, String tableDescription, List<BigDecimal> rvalue, String leftAndRightOpt) {
        String retValue = "";
//        String[] temp=new String[2];
//        temp[0]=rvalue.get(0).toString();
//        temp[1]=rvalue.get(1).toString();
        Boolean isSuccess;
        isSuccess = checkResult2(rvalue, leftAndRightOpt);
        if (isSuccess) {
//            retValue = "稽核单位：" + zt.get(1) + " " + tableDescription + " " + ruleDescription + " 左值：" + rvalue.get(0).toString() + " 右值：" + rvalue.get(1).toString();
            retValue = messageHead + tableDescription + " " + ruleDescription + " 左值：" + rvalue.get(0) + " 右值：" + rvalue.get(1);
        }
        //System.out.println(retValue);
        return retValue;
    }

    private static Boolean checkResult2(List<BigDecimal> temp, String leftAndRightOpt) {
        Boolean isSuccess = false;
        if (leftAndRightOpt.equalsIgnoreCase("=")) {
            isSuccess = temp.get(0).compareTo(temp.get(1)) == 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase("!=")) {
            isSuccess = temp.get(0).compareTo(temp.get(1)) != 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase("<=")) {
            isSuccess = temp.get(0).compareTo(temp.get(1)) <= 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase(">=")) {
            isSuccess = temp.get(0).compareTo(temp.get(1)) >= 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase("<")) {
            isSuccess = temp.get(0).compareTo(temp.get(1)) < 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase(">")) {
            isSuccess = temp.get(0).compareTo(temp.get(1)) > 0;
        }
        //System.out.println(temp.get(0).toString() + temp.get(1).toString() + "---");
        return isSuccess;
    }

    private static Boolean checkResult(String[] temp, String leftAndRightOpt) {
        Boolean isSuccess = false;
        if (leftAndRightOpt.equalsIgnoreCase("=")) {
            isSuccess = temp[0].compareTo(temp[1]) == 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase("!=")) {
            isSuccess = temp[0].compareTo(temp[1]) != 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase("<=")) {
            isSuccess = temp[0].compareTo(temp[1]) <= 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase(">=")) {
            isSuccess = temp[0].compareTo(temp[1]) >= 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase("<")) {
            isSuccess = temp[0].compareTo(temp[1]) < 0;
        }
        if (leftAndRightOpt.equalsIgnoreCase(">")) {
            isSuccess = temp[0].compareTo(temp[1]) > 0;
        }
        //System.out.println(temp[0] + temp[1] + "---");
        return isSuccess;
    }

    private static String getLeftAndRightOpt(String gongShi, String leftAndRightOpt) {
        if (gongShi.contains("=")) {
            if (gongShi.contains("!=")) {
                leftAndRightOpt = "!=";
            } else if (gongShi.contains("<=")) {
                leftAndRightOpt = "<=";
            } else if (gongShi.contains(">=")) {
                leftAndRightOpt = ">=";
            } else {
                leftAndRightOpt = "=";
            }

        } else {
            if (gongShi.contains("<")) {
                leftAndRightOpt = "<";
            }
            if (gongShi.contains(">")) {
                leftAndRightOpt = ">";
            }
        }
        return leftAndRightOpt;
    }

    private static void setValueList(String rightValueStr, List<List<String>> valueList, List<String> rightValueList, Matcher m) {
        while (m.find()) {
            rightValueList.add(m.group());
        }
        if (rightValueList.size() == 0) {
            rightValueList.add(rightValueStr);
        } else {
            String lastStr = rightValueList.get(rightValueList.size() - 1);
            String opt = "\\" + lastStr.substring(lastStr.length() - 1);
            String[] temp = rightValueStr.split(opt);
            rightValueList.add(temp[temp.length - 1]);
        }
        valueList.add(rightValueList);
    }

}
